#ifndef _PARTHUS_SCO_CONTAINER_
#define _PARTHUS_SCO_CONTAINER_

/******************************************************************************
 * MODULE NAME:    lmp_sco_container.h
 * PROJECT CODE:    BlueStream
 * DESCRIPTION:   
 * MAINTAINER:     Gary Fleming
 * CREATION DATE:        
 *
 * SOURCE CONTROL: $Id: lmp_sco_container.h,v 1.6 2008/11/08 07:30:04 tianwq Exp $
 *
 * LICENSE:
 *     This source code is copyright (c) 2000-2004 Ceva Inc.
 *     All rights reserved.
 *
 * REVISION HISTORY:
 *
 ******************************************************************************/

#include "sys_types.h"
#include "lmp_acl_connection.h"    

void LMscoctr_Initialise(void);

t_sco_info *LMscoctr_Alloc(t_deviceIndex device_index, u_int16 voice_setting, t_linkType link_type);
void LMscoctr_Free(t_sco_info *p_sco_link);
void LMscoctr_Free_SCOs_On_Link(t_deviceIndex device_index);

#if ((PRH_BS_CFG_SYS_LMP_SCO_SUPPORTED==1) || (PRH_BS_CFG_SYS_LMP_EXTENDED_SCO_SUPPORTED == 1))

u_int8  LMscoctr_Get_Number_SCO_Connections(void);
u_int8  LMscoctr_Get_Number_SYN_Connections(void);
u_int8 LMscoctr_Get_Number_PCM_Connections(void);
u_int8  LMscoctr_Is_All_Bandwidth_Used_By_SCO(void);
u_int8  LMscoctr_Is_All_Bandwidth_Used_By_SYN(void);
u_int8  LMscoctr_Get_Number_SCOs_Active_On_Link(t_deviceIndex device_index);
u_int8  LMscoctr_Get_Number_SCOs_Active(void);
#else
/*
 * If No SCOs then stub to 0
 */
#define LMscoctr_Get_Number_SCO_Connections()       (0)
#define LMscoctr_Get_Number_SYN_Connections()       (0)
#define LMscoctr_Get_Number_PCM_Connections()     (0)
#define LMscoctr_Is_All_Bandwidth_Used_By_SCO()     (0)
#define LMscoctr_Get_Number_SCOs_Active_On_Link(device_index) (0)

#endif

#define ESCO_DONT_CARE_BANDWIDTH 0xFFFFFFFF
#define ESCO_DONT_CARE_LATENCY   0xFFFF
#define ESCO_DONT_CARE_PACKETTYPE   0xFFFF
#define ESCO_DONT_CARE_RETRANSMISSION_EFFORT 0xFF

typedef enum 
{
    ESCO_SETUP,
    ESCO_RECONFIGURE,
    ESCO_REMOVE,
    ESCO_IDLE
} t_esco_transaction_type;

typedef enum 
{
    ESCO_NGT_INIT = 0,
    ESCO_NGT_OTHER,
    ESCO_NGT_RESERVED_SLOT,
    ESCO_NGT_LATENCY,
    ESCO_NGT_UNSUPPORTED_FEATURE,
    ESCO_NGT_NO_ERROR,
    ESCO_NGT_NOT_ACCEPT
} t_esco_neg_state ;

typedef enum 
{
    FIRST_NEW_ESCO_PDU,
    CONTINUE_NEW_ESCO_PDU,
    FIRST_CHANGE_ESCO_PDU,
    CONTINUE_CHANGE_ESCO_PDU
} t_esco_link_req_context;

typedef struct s_lm_esco_pkt_type_desc {
    t_packetTypes type_mask;
    t_packet type;
    u_int16 max_len;
    u_int8 slots;
} t_lm_esco_pkt_type_desc;

typedef enum {
    LINEAR_IC,
    U_LAW_IC,
    A_LAW_IC,
    CVSD_IC
} t_input_coding;

typedef enum 
{
    ONES_COMP_IDF,
    TWOS_COMP_IDF,
    SIGN_MAG_IDF,
    UNSIGNED_IDF
} t_input_data_format;

typedef enum 
{
    EIGHT_BIT_ISS,
    SIXTEEN_BIT_ISS
} t_input_sample_size;

typedef enum 
{
    CVSD_ACF,
    U_LAW_ACF,
    A_LAW_ACF,
    TRANS_ACF
} t_air_coding_format;

typedef enum 
{
    REGULAR_RETRANS,
    SHARED_RETRANS
} t_esco_retrans_mode;

__INLINE__ t_air_coding_format LMscoctr_Get_Air_Coding(u_int16 voice_setting);
__INLINE__ u_int8 LMscoctr_Get_Linear_PCM_Bit_Pos(u_int16 voice_setting);
__INLINE__ t_input_coding LMscoctr_Get_Input_Coding(u_int16 voice_setting);
__INLINE__ t_input_data_format LMscoctr_Get_Input_Data_Format(u_int16 voice_setting);
__INLINE__ t_input_sample_size LMscoctr_Get_PCM_Sample_Size(u_int16 voice_setting);
__INLINE__ u_int8 LMscoctr_Get_Input_Sample_Size(u_int16 voice_setting);

t_sco_info *LMscoctr_Find_SCO_By_Connection_Handle(t_connectionHandle connection_handle);
t_sco_info *LMscoctr_Find_SCO_By_SCO_Handle(u_int8 sco_handle);
t_sco_info *LMscoctr_Find_SCO_By_SCO_Index(u_int8 index);
t_sco_info *LMscoctr_Find_SCO_By_Device_Index(t_deviceIndex device_index);

u_int8 LMscoctr_Convert_HCI_To_LM_SCO_Packet_Type(t_packetTypes packet_type);

u_int8  LMscoctr_Is_Bandwidth_Available_For_SCO_Packet_Types(
    t_packetTypes packet_types);

__INLINE__ u_int8  LMscoctr_Get_SCO_Index(const t_sco_info *p_sco_link);

void LMscoctr_Assign_SCO_Parameters(
    t_sco_info *p_sco_link_dest, const t_sco_info *p_sco_link_source);
void LMscoctr_Derive_SCO_Parameters(
    t_sco_info *p_sco_link, t_packetTypes packet_types, t_role role,
    u_int8 use_peer_air_mode_flag);

t_error LMscoctr_Extract_SCO_Parameters_From_PDU(
    t_sco_info *p_sco_link, t_p_pdu p_pdu, t_role role);

u_int8 LMscoctr_Map_AirMode_HCI2LMP(u_int8 hc_air_mode);
u_int8 LMscoctr_Map_AirMode_LMP2HCI(u_int8 lm_air_mode);
u_int8 LMscoctr_Derive_LM_SCO_Packet_Type(
    const t_sco_info *p_sco_link, t_packetTypes packet_types);
u_int8 LMscoctr_Get_Active_LM_SCO_Packet_Type(void);
u_int8 LMscoctr_Get_Used_LM_SCO_Packet_Type(void);
u_int8 LMscoctr_Get_Active_LM_SYN_Window(void);
boolean LMscoctr_Is_LM_Air_Mode_Supported(u_int8 lm_air_mode);
t_sco_info* LMscoctr_Get_SCO_Transitioning_Ref(void);
t_sco_info* LMscoctr_Find_SCO_Under_Negotiation(t_role role);

t_sco_info *LMscoctr_Allocate_Negotation_SCO_Link(
     const t_sco_info *p_sco_link, t_role role, 
     t_packetTypes packet_types, u_int8 lm_air_mode);
void LMscoctr_Free_Negotiation_SCO_Link(void);
void LMscoctr_Accept_And_Free_Negotiated_SCO_Link(t_sco_info *p_sco_link);

__INLINE__ u_int8 LMeScoctr_Get_Tx_Packet_Type_in_Slots(const t_sco_info *p_sco_link);
__INLINE__ u_int8 LMeScoctr_Get_Rx_Packet_Type_in_Slots(const t_sco_info *p_sco_link);
__INLINE__ u_int8 LMscoctr_GetSlotOccupancy(t_packet packet_type);

__INLINE__ u_int8 LMeScoctr_Get_Number_eSCO_Connections(void);

u_int8 LMscoctr_Map_eSCO_Pkt_Type_HCI2LMP(u_int16 packet_types);
u_int16 LMscoctr_Map_eSCO_Pkt_Type_LMP2HCI(u_int8 packet_type);
void LMscoctr_Extract_eSCO_Parameters_From_LMP_PDU(
    t_p_pdu p_pdu);
t_error LMscoctr_Validate_Host_eSCO_Parameters(t_lmp_link *p_link);
t_error LMscoctr_Validate_Peer_eSCO_Parameters(t_lmp_link* p_link,
        u_int8* p_pdu);
t_error LMscoctr_Validate_SYN_Piconet(t_lmp_link* p_link);

__INLINE__ t_sco_info* LMscoctr_Get_Topical_eSCO_Link(void);
__INLINE__ t_esco_transaction_type LMscoctr_Get_Topical_eSCO_Link_Transaction_Type(void);
__INLINE__ void LMscoctr_Set_Topical_eSCO_Link(t_sco_info* p_esco_link, t_esco_transaction_type type);

__INLINE__ t_lmp_link* LMscoctr_Find_ACL_Link_From_SCO_Link(t_sco_info* p_esco);
void LMscoctr_Commit_to_New_Synchronous_Parameters(t_sco_info* p_esc);

void LMscoctr_Initial_Negotiate_Setting(void);
void LMscoctr_Adjust_Negotiate_Setting(void);
boolean LMscoctr_Get_Next_LMP_Parameter_Set(void);

t_esco_neg_state LMscoctr_Check_eSCO_Parameter(t_esco_descr* p_esco_descr);
__INLINE__ t_esco_descr* LMscoctr_Get_eSCO_Scratchpad(void);
__INLINE__ void LMscoctr_Clean_eSCO_Scratchpad(void);
__INLINE__ t_esco_host_constraints * LMscoctr_Get_eSCO_Host_Constraints(void);

void LMscoctr_Set_D_eSCO_and_Timing_Flag(t_esco_descr* p_esco_descr);
void LMscoctr_Init_D_eSCO_Bitmap(t_sco_info* p_self_esco_link);
s_int16 LMscoctr_Derive_D_eSCO_AtLeast(u_int8 init_d_esco, 
    t_sco_info* p_self_esco_link, t_esco_descr* p_esco_descr);
boolean LMscoctr_Is_D_eSCO_Acceptable(t_esco_descr* p_esco_descr, t_lmp_link* p_link);
s_int16 LMscoctr_Get_Next_D_eSCO(t_sco_info* p_self_esco_link, t_esco_descr* p_esco_descr);

__INLINE__ void LMscoctr_Suspend_Link(t_sco_info* p_esco_link);
__INLINE__ void LMscoctr_Resume_Link(t_sco_info* p_esco_link);

u_int16 LMscoctr_Derive_Tx_Dequeue_Length(t_sco_info* p_esco_link);
u_int16 LMscoctr_Derive_Rx_Dequeue_Length(t_sco_info* p_esco_link);

/*
 * The following routines are used on slave-initiated SCO when
 * the IUT is a slave - it frees and re-allocates the SCO container
 * (losing the voice setting information. Store that voice
 * information in a holding variable.
 */
__INLINE__ void LMscoctr_Store_Topical_Voice_Setting(u_int16 voice_setting);
__INLINE__ u_int16 LMscoctr_Restore_Topical_Voice_Setting(void);

/*
 * The following routines are used to set and get the eSCO retransmission
 * mode. Either shared or unshared.
 */
#if (PRH_BS_CFG_SYS_ESCO_SHARED_RETRANSMISSION_SUPPORTED == 1)
t_esco_retrans_mode LMscoctr_Get_eSCO_Retransmission_Mode(void);
void LMscoctr_Set_eSCO_Retransmission_Mode(t_esco_retrans_mode mode);
void LMscoctr_Order_LMP_Parameter_Sets_For_Shared_Retransmission(void);

/*
 * The following routines are used in shared eSCO retransmission mode.
 */
u_int8 LMscoctr_Get_Next_Sco_Index(u_int8 curr_index);
u_int8 LMscoctr_Get_Next_Retransmission_Index(u_int8 last_index, u_int8* list, u_int8 num_in_list);
#endif

#ifdef __USE_INLINES__
#include "lmp_sco_impl.h"
#endif

#endif
